<template>
  <div
    ref="floatDrag"
    class="levitated-sphere-float"
    :class="{ 'half-hidden': isHalfHidden }"
    :style="{
      top: data.top + 'px', 
      right: data.right + 'px',
      borderRadius: borderRadius,
      width: width + 'px',
      height: height + 'px',
      ...customStyle
    }"
    @touchmove.prevent
    @mousemove.prevent
    @mousedown.stop="mouseDown"
  >
    <!-- @click="handleClick" -->
    <slot>
      <div
        class="levitated-sphere-content"
        :style="{
          width: width * 0.7 + 'px',
          height: height * 0.7 + 'px'
        }"
      >
        <!-- 默认图标 -->
        <svg viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
          <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
        </svg>
      </div>
    </slot>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted, onBeforeUnmount } from 'vue'

// 定义组件属性
interface Props {
  // 悬浮球宽度
  width?: number
  // 悬浮球高度
  height?: number
  // 距离右侧距离
  distanceRight?: number
  // 距离底部距离
  distanceBottom?: number
  // 是否可拖拽
  draggable?: boolean
  // 自定义样式
  customStyle?: Record<string, string>
  // 圆角
  borderRadius?: string
  // 新增：自动隐藏
  autoHide?: boolean
  autoHideDelay?: number
}

// 定义事件
const emit = defineEmits<{
  (e: 'click'): void
}>()

// 设置默认值
const props = withDefaults(defineProps<Props>(), {
  width: 50,
  height: 50,
  distanceRight: 0,
  distanceBottom: 100,
  draggable: true,
  customStyle: () => ({}),
  borderRadius: '50%',
  autoHide: true,
  autoHideDelay: 5000
//   autoHideDelay: 10000
})

// 响应式数据
const data = reactive({
  clientWidth: 0,
  clientHeight: 0,
  right: props.distanceRight,
  top: 0,
  mousedownX: 0,
  mousedownY: 0,
  hasMoved: false // 新增：用于标记是否发生过拖拽
})

const floatDrag = ref<HTMLElement | null>(null)
// 触摸事件处理
const touchStart = () => {
  if (floatDrag.value) {
    floatDrag.value.style.transition = 'none'
  }
  resetHideTimer()
}

const touchMove = (e: TouchEvent) => {
  if (!floatDrag.value || e.targetTouches.length !== 1) return
  
  const touch = e.targetTouches[0]
  data.right = data.clientWidth - touch.clientX - floatDrag.value.offsetWidth / 2
  data.top = touch.clientY - floatDrag.value.offsetHeight / 2
}

const touchEnd = () => {
  if (floatDrag.value) {
    floatDrag.value.style.transition = 'all 0.3s'
  }
  checkPosition()
}

// 点击事件处理
const handleClick = () => {
  if (isHalfHidden.value) {
    isHalfHidden.value = false
    resetHideTimer()
    return
  }
  emit('click')
  resetHideTimer()
}


// 初始化位置和尺寸
onMounted(() => {
  data.clientWidth = document.documentElement.clientWidth
  data.clientHeight = document.documentElement.clientHeight
  
  if (floatDrag.value) {
    data.top = data.clientHeight - props.height - props.distanceBottom
  }

  if (props.draggable) {
    initDraggable()
  }
  
  window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
})

// 初始化拖拽功能
const initDraggable = () => {
  if (!floatDrag.value) return
  
  floatDrag.value.addEventListener('touchstart', touchStart)
  floatDrag.value.addEventListener('touchmove', touchMove)
  floatDrag.value.addEventListener('touchend', touchEnd)
}

// 处理窗口大小变化
const handleResize = () => {
  data.clientWidth = document.documentElement.clientWidth
  data.clientHeight = document.documentElement.clientHeight
  checkPosition()
}

// 检查并调整位置
const checkPosition = () => {
  if (!floatDrag.value) return

  // 检查水平位置
  if (data.right + floatDrag.value.offsetWidth / 2 >= data.clientWidth / 2) {
    data.right = data.clientWidth - floatDrag.value.offsetWidth
  } else {
    data.right = 0
  }

  // 检查垂直位置
  if (data.top < 0) {
    data.top = 0
  }
  if (data.top + floatDrag.value.offsetHeight >= data.clientHeight) {
    data.top = data.clientHeight - floatDrag.value.offsetHeight
  }
}
const mouseDown = (e: MouseEvent) => {
  const event = e || window.event
  data.mousedownX = event.screenX
  data.mousedownY = event.screenY
  data.hasMoved = false // 每次按下重置

  if (floatDrag.value) {
    floatDrag.value.style.transition = 'none'
  }

  document.onmousemove = mouseMoveHandler
  document.onmouseup = mouseUp
}

const mouseUp = (e: MouseEvent) => {
  // 判断移动距离是否小于阈值，若是则触发点击
  const event = e //|| window.event
  const deltaX = Math.abs(event.screenX - data.mousedownX)
  const deltaY = Math.abs(event.screenY - data.mousedownY)
  const CLICK_THRESHOLD = 5 // 阈值像素

  if (deltaX < CLICK_THRESHOLD && deltaY < CLICK_THRESHOLD) {
    handleClick()
  }

  document.onmousemove = null
  document.onmouseup = null
  if (floatDrag.value) {
    floatDrag.value.style.transition = 'all 0.3s'
  }
  checkPosition()
}

// 新增：自动隐藏相关
const isHalfHidden = ref(false)
let hideTimer: number | null = null

// 重置自动隐藏定时器
const resetHideTimer = () => {
  if (!props.autoHide) return
  if (hideTimer) {
    clearTimeout(hideTimer)
    hideTimer = null
  }
  isHalfHidden.value = false
  hideTimer = window.setTimeout(() => {
    isHalfHidden.value = true
  }, props.autoHideDelay)
}

// 鼠标事件处理
// const mouseDown = (e: MouseEvent) => {
 
//     const event = e || window.event
//   data.mousedownX = event.screenX
//   data.mousedownY = event.screenY
//   data.hasMoved = false // 每次按下重置

//   if (floatDrag.value) {
//     floatDrag.value.style.transition = 'none'
//   }

//   document.onmousemove = mouseMoveHandler
//   document.onmouseup = mouseUp // 新增：绑定 mouseup 到 document
// }

const mouseMoveHandler = (e: MouseEvent) => {
  if (!floatDrag.value) return

  const event = e || window.event
  const floatDragWidth = floatDrag.value.offsetWidth / 2
  const floatDragHeight = floatDrag.value.offsetHeight / 2

  data.right = data.clientWidth - event.clientX - floatDragWidth
  data.top = event.clientY - floatDragHeight

  // 只要发生过移动就标记
  data.hasMoved = true

  // 边界检查
  if (data.right < 0) data.right = 0
  if (data.top < 0) data.top = 0
  if (data.right > data.clientWidth - floatDrag.value.offsetWidth) {
    data.right = data.clientWidth - floatDrag.value.offsetWidth
  }
  if (data.top > data.clientHeight - floatDrag.value.offsetHeight) {
    data.top = data.clientHeight - floatDrag.value.offsetHeight
  }
}
// 初始化时启动定时器
onMounted(() => {
  data.clientWidth = document.documentElement.clientWidth
  data.clientHeight = document.documentElement.clientHeight
  
  if (floatDrag.value) {
    data.top = data.clientHeight - props.height - props.distanceBottom
  }

  if (props.draggable) {
    initDraggable()
  }
  
  window.addEventListener('resize', handleResize)
})

// 离开页面时清理定时器
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  if (hideTimer) clearTimeout(hideTimer)
})
</script>

<style scoped>


.levitated-sphere-float {
  position: fixed;
  z-index: 99999;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  transition: all 0.3s;
}

.levitated-sphere-content {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.half-hidden {
  /* 右侧隐藏一半 */
  /* transform: translateX(50%);
  opacity: 0.7;
  pointer-events: auto; */
}

</style>